#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

import sys

from common.common import exter_attack, get_host_sn
from common.const import SysData
from exchange import log
from exchange.backup.backup_base.base_exchange_backup_gen_sub_job import ExchangeBackupBackupGenSubJob
from exchange.commons.common import output_result_file, get_mailbox_database_copy_status, get_key_value
from exchange.commons.const import ExchangeJobInfo, SubJobPolicy, ExchangeBackupSubJobName, \
    SubJobPriorityEnum, JobBackupType
from exchange.commons.exchange_exception import ExchangeErrCodeException
from exchange.commons.exchange_function_tool import log_start_end


class DatabaseBackupGenSubJob(ExchangeBackupBackupGenSubJob):
    def __init__(self, pid):
        super().__init__(pid)
        self._pid = pid

    @log_start_end()
    def do_gen_sub_job_task(self, job_info: ExchangeJobInfo):
        # 主副本备份默认获取本地agent_id
        node_id = get_host_sn()
        # 默认拆分拆分到主动副本所在节点
        mailbox_server = self._param.get("job").get("protectObject").get("extendInfo").get("server_name")
        # 单库备份需要区分是否备份被动数据库，将子任务拆分到对应节点
        # 获取数据库名称
        db_name = self._param.get("job").get("protectObject").get("name")
        log.info(f"do_gen_sub_job_task dbname:{db_name}")
        # 是否需要备份被动数据库
        dag_backup = self._param.get("job").get("protectObject").get("extendInfo").get("dag_backup")
        if dag_backup == "passive":
            flags, m_username = get_key_value(f'job_protectEnv_auth_authKey_{job_info.pid}')
            flags, m_password = get_key_value(f'job_protectEnv_auth_authPwd_{job_info.pid}')
            copy_list = get_mailbox_database_copy_status(m_username, m_password, db_name)
            log.info(f"passive copy list :{copy_list}")
            if len(copy_list) != 0:
                # 获取最高激活选项的副本
                highest_activation_preference_copy = min(copy_list, key=lambda x: x['activationPreference'])
                # 获取最高激活选项副本所在的node_id
                mailbox_server = highest_activation_preference_copy["mailboxServer"]
            log.info(f"database back up in {mailbox_server}")
        nodes = self._param.get("job").get("protectEnv").get("nodes")
        for node in nodes:
            if node["name"].upper() == mailbox_server.upper():
                node_id = node['id']
                break
        log.info(f"Get agent node id {node_id}")
        response = []
        # 第一个子任务，创建备份任务
        job_policy = SubJobPolicy.FIXED_NODE.value
        job_name = ExchangeBackupSubJobName.SUB_EXEC
        job_priority = SubJobPriorityEnum.JOB_PRIORITY_1.value
        response.append(self.build_sub_job(job_priority, job_policy, job_name, node_id, job_info))

        # 日志备份场景，第二个子任务，上报备份副本时间
        log.info("Gen sub job upload log copy sub job")
        node_id = self._param.get("job").get("protectEnv").get("nodes")[0].get("id", "")
        job_policy1 = SubJobPolicy.LOCAL_NODE.value
        job_name = ExchangeBackupSubJobName.SUB_UPLOAD
        job_priority = SubJobPriorityEnum.JOB_PRIORITY_2.value
        response.append(self.build_sub_job(job_priority, job_policy1, job_name, node_id, job_info))

        log.info(f"Gen sub job result： {response}")
        output_result_file(job_info.pid, response)
        return True


@exter_attack
def do_exec(pid):
    try:
        job = DatabaseBackupGenSubJob(pid)
        job.do_gen_sub_job_task(job.get_job_info())
    except ExchangeErrCodeException as err_str:
        log.error(f"Post backup failed, err: {err_str}, pid:{pid}")
        return False
    return True

if __name__ == '__main__':
    for line in sys.stdin:
        SysData.SYS_STDIN = line
        break

    if len(sys.argv) < 1:
        log.error("Param is wrong.")
        sys.exit(1)
    pid_args2 = sys.argv[1]
    try:
        do_exec(pid_args2)
    except Exception as err:
        log.error(f"Err: {err}, pid: {pid_args2}")
        sys.exit(0)

    sys.exit(0)